package week

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"menu-generation-go/database"
	"menu-generation-go/handlers/common"
	"menu-generation-go/models"
	"sort"
	"strconv"
	"time"
)

type DayMenuHandler struct {
	DB *database.Database
}

func NewDayMenuHandler(db *database.Database) *DayMenuHandler {
	return &DayMenuHandler{DB: db}
}

// GetWeekMenuDetail 获取周菜单详情
// @Summary 获取周菜单详情
// @Description 获取周菜单及其每日菜品详情
// @Tags 每日菜单
// @Accept json
// @Produce json
// @Param id path int true "周菜单ID"
// @Success 200 {object} common.Response{data=WeekMenuDetailResponse}
// @Router /api/week-menus/{id} [get]
func (h *DayMenuHandler) GetWeekMenuDetail(c *gin.Context) {
	type GetWeekMenuDetailRequest struct {
		ID int `json:"id"`
	}

	var input GetWeekMenuDetailRequest
	if err := c.ShouldBindJSON(&input); err != nil {
		common.SendErrJSON("无效ID:"+err.Error(), c)
		return
	}
	if input.ID == 0 {
		common.SendErrJSON("无效ID", c)
		return
	}
	type DishGroup struct {
		LunchDishes  []models.MenuDishes `json:"lunch_dishes"`
		DinnerDishes []models.MenuDishes `json:"dinner_dishes"`
	}

	type DayDetail struct {
		Date    string    `json:"date"`
		Weekday string    `json:"weekday"`
		Lunch   DishGroup `json:"lunch"`
		Dinner  DishGroup `json:"dinner"`
		Status  string    `json:"status"`
	}

	type WeekMenuDetailResponse struct {
		WeekMenu models.WeekMenus `json:"week_menu"`
		Days     []DayDetail      `json:"days"`
	}

	// 获取周菜单
	var weekMenu models.WeekMenus
	if err := h.DB.DB.First(&weekMenu, input.ID).Error; err != nil {
		common.SendErrJSON("周菜单不存在", c)
		return
	}

	// 获取所有每日菜单
	var dayMenus []models.DayMenus
	if err := h.DB.DB.Where("week_menu_id = ?", input.ID).Find(&dayMenus).Error; err != nil {
		common.SendErrJSON("查询每日菜单失败", c)
		return
	}

	// 获取所有菜品关联
	var menuDishes []models.MenuDishes
	if err := h.DB.DB.Where("day_menu_id IN (SELECT id FROM day_menus WHERE week_menu_id = ?)", input.ID).Find(&menuDishes).Error; err != nil {
		common.SendErrJSON("查询菜品失败", c)
		return
	}

	// 构建响应
	response := WeekMenuDetailResponse{
		WeekMenu: weekMenu,
	}

	// 按日期分组
	dateMap := make(map[string]DayDetail)
	for _, dm := range dayMenus {
		detail, exists := dateMap[dm.Date]
		if !exists {
			detail = DayDetail{
				Date:    dm.Date,
				Weekday: dm.TheWeek,
				Lunch: DishGroup{
					LunchDishes: []models.MenuDishes{},
				},
				Dinner: DishGroup{
					DinnerDishes: []models.MenuDishes{},
				},
			}
		}

		// 检查该日期是否已完成
		if dm.Status == "completed" {
			detail.Status = "completed"
		} else {
			detail.Status = "pending"
		}

		// 添加菜品到对应餐型
		for _, dish := range menuDishes {
			if dish.DayMenuID == dm.ID {
				if dm.MealType == "lunch" {
					detail.Lunch.LunchDishes = append(detail.Lunch.LunchDishes, dish)
				} else {
					detail.Dinner.DinnerDishes = append(detail.Dinner.DinnerDishes, dish)
				}
			}
		}

		dateMap[dm.Date] = detail
	}

	// 转换为切片
	for _, detail := range dateMap {
		response.Days = append(response.Days, detail)
	}
	// 按日期从小到大排序
	sort.Slice(response.Days, func(i, j int) bool {
		return response.Days[i].Date < response.Days[j].Date
	})

	common.Ok(c, response)
}

// UpdateDayMenuDishes 更新每日菜单菜品
// @Summary 更新每日菜单菜品
// @Description 更新指定日期的餐型菜品
// @Tags 每日菜单
// @Accept json
// @Produce json
// @Param id path int true "每日菜单ID"
// @Param input body UpdateDayMenuRequest true "菜品信息"
// @Success 200 {object} common.Response
// @Router /api/day-menus/{id} [put]
func (h *DayMenuHandler) UpdateDayMenuDishes(c *gin.Context) {
	type DishInput struct {
		RecipeID   uint   `json:"recipe_id" binding:"required"`
		RecipeName string `json:"recipe_name" binding:"required"`
	}

	type UpdateDayMenuRequest struct {
		MealType string      `json:"meal_type" binding:"required"`
		Dishes   []DishInput `json:"dishes" binding:"required"`
	}

	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		common.SendErrJSON("无效ID", c)
		return
	}

	var input UpdateDayMenuRequest
	if err := c.ShouldBindJSON(&input); err != nil {
		common.SendErrJSON("无效输入: "+err.Error(), c)
		return
	}

	// 验证菜品数量
	if len(input.Dishes) != 5 {
		common.SendErrJSON("必须选择5个菜品(4菜1汤)", c)
		return
	}

	// 检查是否包含汤类
	hasSoup := false
	for _, dish := range input.Dishes {
		var recipe models.MenuRecipe
		if err := h.DB.DB.First(&recipe, dish.RecipeID).Error; err == nil {
			if recipe.Type == 4 {
				hasSoup = true
				break
			}
		}
	}

	if !hasSoup {
		common.SendErrJSON("必须包含一个汤类菜品", c)
		return
	}

	tx := h.DB.DB.Begin()

	// 删除原有菜品
	if err := tx.Where("day_menu_id = ?", id).Delete(&models.MenuDishes{}).Error; err != nil {
		tx.Rollback()
		common.SendErrJSON("清除旧菜品失败", c)
		return
	}

	// 添加新菜品
	for _, dish := range input.Dishes {
		menuDish := models.MenuDishes{
			DayMenuID:  uint(id),
			RecipeID:   dish.RecipeID,
			RecipeName: dish.RecipeName,
			CreatedAt:  time.Now(),
			UpdatedAt:  time.Now(),
		}
		if err := tx.Create(&menuDish).Error; err != nil {
			tx.Rollback()
			common.SendErrJSON("添加菜品失败", c)
			return
		}
	}

	// 更新每日菜单状态
	if err := tx.Model(&models.DayMenus{}).Where("id = ?", id).Update("status", "completed").Error; err != nil {
		tx.Rollback()
		common.SendErrJSON("更新状态失败", c)
		return
	}

	// 检查周菜单完成状态
	if err := h.checkWeekCompletion(tx, uint(id)); err != nil {
		tx.Rollback()
		common.SendErrJSON("检查周菜单状态失败", c)
		return
	}

	tx.Commit()
	common.Ok(c, gin.H{"message": "更新成功"})
}

// 检查周菜单完成状态
func (h *DayMenuHandler) checkWeekCompletion(tx *gorm.DB, dayMenuID uint) error {
	// 获取对应的每日菜单
	var dayMenu models.DayMenus
	if err := tx.First(&dayMenu, dayMenuID).Error; err != nil {
		return err
	}

	// 获取该周的所有每日菜单
	var dayMenus []models.DayMenus
	if err := tx.Where("week_menu_id = ?", dayMenu.WeekMenuID).Find(&dayMenus).Error; err != nil {
		return err
	}

	// 检查是否所有每日菜单都已完成
	allCompleted := true
	for _, dm := range dayMenus {
		if dm.Status != "completed" {
			allCompleted = false
			break
		}
	}

	// 更新周菜单状态
	if allCompleted {
		if err := tx.Model(&models.WeekMenus{}).
			Where("id = ?", dayMenu.WeekMenuID).
			Update("status", "completed").Error; err != nil {
			return err
		}
	}

	return nil
}
